package com.hymall.controller.wx;

import com.hymall.aliyun.AliyunUtils;
import com.hymall.bean.WxInfoBean;
import com.hymall.bean.MarketUser;
import com.hymall.bean.WxRegisterCode;
import com.hymall.bean.WxRegisterCodeExample;
import com.hymall.bean.bo.WxRegisterBo;
import com.hymall.bean.common.BaseRespVo;
import com.hymall.bean.vo.WxAughLoginVO;
import com.hymall.bean.vo.WxRegisterVo;
import com.hymall.mapper.MarketUserMapper;
import com.hymall.mapper.WxRegisterCodeMapper;
import com.hymall.realm.MarketToken;
import com.hymall.service.wx.WxCouponService;
import com.hymall.service.wx.WxUserService;
import com.hymall.service.wx.WxAuthService;
import com.hymall.util.DateUtils;
import com.hymall.util.Md5Util;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author: 章鹏
 * @description 用户 → 账号登录
 * @date: 2022/7/19 9:01
 */
@RestController
@RequestMapping("wx/auth")
public class WxAuthorController {

    @Autowired
    WxUserService wxUserService;


    @Autowired
    AliyunUtils aliyun;

    @Autowired
    WxAuthService wxAuthService;

    @Autowired
    WxCouponService wxCouponService;

    /**
     * @param [map]
     * @return com.hymall.bean.common.BaseRespVo
     * @author 章鹏
     * @description shiro整合之后，在做具体的开发
     * @date 2022/7/19 9:29
     */
    @PostMapping("login")
    public BaseRespVo login(@RequestBody Map map) {
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        MarketToken token = new MarketToken(username, Md5Util.getMd5(password), "wx");
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        }/* catch (AuthenticationException e) {
            e.printStackTrace();
        } */ catch (UnknownAccountException e) {
            //e.printStackTrace();
            return BaseRespVo.error(700, "账号不存在");
        } catch (IncorrectCredentialsException e) {
            //e.printStackTrace();
            return BaseRespVo.error(700, "账号密码不对");
        }
        if (subject.isAuthenticated()) {
            MarketUser marketUser = (MarketUser) subject.getPrincipal();
            WxAughLoginVO loginUserData = new WxAughLoginVO();
            WxInfoBean userInfo = new WxInfoBean();
            userInfo.setAvatarUrl(marketUser.getAvatar());
            userInfo.setNickName(marketUser.getNickname());
            loginUserData.setUserInfo(userInfo);
            String sessionId = (String) subject.getSession().getId();
            loginUserData.setToken(sessionId);
            return BaseRespVo.ok(loginUserData);
        }
        return BaseRespVo.error(400, "登陆失败，请重试");
    }

    /**
     * @param []
     * @return com.hymall.bean.common.BaseRespVo
     * @author 章鹏
     * @description 用户 → 账号登出
     * @date 2022/7/19 9:29
     */
    @PostMapping("logout")
    public BaseRespVo logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return BaseRespVo.ok();
    }


    /**
     * @author 牟治宇
     * @description 密码重置
     * @date 2022/7/20 17:13
     * @param
     * @return
     */
    @Autowired
    MarketUserMapper marketUserMapper;

    @Autowired
    WxRegisterCodeMapper wxRegisterCodeMapper;


    @PostMapping("/reset")
    public BaseRespVo reset(@RequestBody Map<String, String> map) {

        String mobile = map.get("mobile");
        String password = map.get("password");
        String userCode = map.get("code");

        if (mobile.trim().length() != 11) {
            return BaseRespVo.error(402, "手机号格式错误");
        }

        WxRegisterCodeExample wxRegisterCodeExample = new WxRegisterCodeExample();
        wxRegisterCodeExample.createCriteria().andPhoneEqualTo(mobile);

        List<WxRegisterCode> wxRegisterCodes = wxRegisterCodeMapper.selectByExample(wxRegisterCodeExample);

        String code = null;
        for (WxRegisterCode wxRegisterCode : wxRegisterCodes) {
            code = wxRegisterCode.getCode();
        }

        if (!code.equals(userCode)) {
            return BaseRespVo.error(703, "验证码错误");
        }

        String md5 = Md5Util.getMd5(password);

        marketUserMapper.resetPassword(mobile, md5);

        return BaseRespVo.ok();
    }

    /**
     * 短信验证
     *
     * @author: 叶熠彬
     * @date: 2022/7/20 12:30
     * @param: [map]
     * @return: com.hymall.bean.common.BaseRespVo
     */
    @PostMapping("regCaptcha")
    public BaseRespVo regCaptcha(@RequestBody Map<String, String> map) {

        String mobile = map.get("mobile");
        if (!mobile.matches("^1(3|4|5|7|8)\\d{9}$")) {
            return BaseRespVo.error(402, "手机号格式错误");
        }
        //一分钟内不可多次请求
        Date nowTime = new Date();
        Date lastTime = wxAuthService.queryLastGetCodeTime(mobile);
        if (lastTime != null && DateUtils.addMinutes(lastTime, 1).after(nowTime)) {
            return BaseRespVo.error(702, "验证码未超时1分钟，不能发送");
        }

        //生成6位验证码
        String code = RandomStringUtils.randomNumeric(6);
        try {
            //有数量限制，不要疯狂debug……
            aliyun.sendMsg(mobile, code);
        } catch (Exception e) {
            e.printStackTrace();
            return BaseRespVo.invalidData("请稍后重试");
        }
        wxAuthService.addCodeByPhone(mobile, code);
        return BaseRespVo.ok();
    }


    /**
     * 填完所有信息后进行登录
     * 增加了注册成功后自动发放新人优惠券的功能
     * 增加了注册成功后跳转回首页的功能
     *
     * @author: 叶熠彬
     * @date: 2022/7/20 16:42
     * @param: [bo]
     * @return: com.hymall.bean.common.BaseRespVo
     */
    @PostMapping("register")
    public BaseRespVo register(@RequestBody WxRegisterBo bo, HttpServletResponse response) {
        //数据校验前端已经做好了
        int code = wxAuthService.addWxUser(bo);
        if (code == 704) {
            return BaseRespVo.error(702, "用户名已占用！");
        }
        if (code == 705) {
            return BaseRespVo.error(702, "手机号已注册！");
        }
        if (code == 703) {
            return BaseRespVo.error(702, "验证码错误！");
        }
        if (code == 0) {
            //根据微信ID发放新人优惠券
            String wxCode = bo.getWxCode();
            wxCouponService.addNewUserCoupon(wxCode);
            Subject subject = SecurityUtils.getSubject();
            MarketToken token = new MarketToken(bo.getUsername(), Md5Util.getMd5(bo.getPassword()), "wx");
            subject.login(token);
            WxRegisterVo vo = new WxRegisterVo();

            WxInfoBean wxInfoBean = new WxInfoBean();
            wxInfoBean.setAvatarUrl("http://182.92.235.201:8083/wx/storage/fetch/45srjkbyvfo3utgxxfdo.gif");
            wxInfoBean.setNickName(bo.getUsername());

            vo.setToken(subject.getSession().getId().toString());
            vo.setUserInfo(wxInfoBean);
            return BaseRespVo.ok(vo);


        }
        return BaseRespVo.error(708, "请稍后重试");

    }

}

